package me.shiqiang.im.linsteners;

import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import me.shiqiang.im.enums.MessageCmd;
import me.shiqiang.im.enums.Metrics;
import me.shiqiang.im.msg.KickoutMsg;
import me.shiqiang.im.msg.Login;
import me.shiqiang.im.redis.RedisKey;
import me.shiqiang.im.server.ConnectionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.metrics.CounterService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author cuishiqiang
 * @date 2017/12/12 下午1:43
 */
@Component("LoginListener")
public class LoginListener extends Listener {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    StringRedisTemplate redisTemplate;

    @Value("${server.id}")
    String serverId;

    @Autowired
    CounterService counterService;

    @OnEvent(MessageCmd.LOGIN)
    public void onLogin(SocketIOClient client, Login login) {
        if (login.isProcessor()) {
            ConnectionContext.getInstance().putProcessor(client);
            return;
        }

        client.set("userId",login.getUserId());
        logger.info("{} 上线",login.getUserId());
        redisTemplate.opsForValue().set(RedisKey.imUserSession(login.getUserId().toString()),
                client.getSessionId().toString() + "@" + serverId, 60, TimeUnit.MINUTES);
        //告诉之前的客户端，被其他客户端登录踢下线
        String previousClientId = ConnectionContext.getInstance().put(login.getUserId().toString(), client.getSessionId().toString());
        if (previousClientId == null) {
            return;
        }
        SocketIOClient previousClient = client.getNamespace().getClient(UUID.fromString(previousClientId));
        if (previousClient != null) {
            KickoutMsg kickoutMsg = new KickoutMsg();
            kickoutMsg.setType(KickoutMsg.MULTI_CLIENT);
            previousClient.sendEvent("kickout", kickoutMsg);
            logger.info("{}被踢下线", login.getUserId());
        }

    }

    @OnConnect
    public void onConnect(SocketIOClient client) {
        counterService.increment(Metrics.SOCKETIO_ONLINE_COUNT);
//        logger.info("在线人数 {}", count);
        System.out.println(client.getRemoteAddress() + " connected!");
    }

    @OnDisconnect
    public void onDisconnect(SocketIOClient client) {
        if (ConnectionContext.getInstance().isProcessor(client)) {
            ConnectionContext.getInstance().delete(client);
            return;
        }
        Long userId = client.get("userId");
        if (userId != null) {
            redisTemplate.delete(RedisKey.imUserSession(userId.toString()));
            logger.info("{} 下线，IP：{}", userId, client.getRemoteAddress());
        }
        counterService.decrement(Metrics.SOCKETIO_ONLINE_COUNT);
    }
}
